package com.hjb.service.impl.withdraw;

import com.fuiou.model.Payforreq;
import com.fuiou.model.Qrytransreq;
import com.hjb.service.config.constant.Constants;
import com.hjb.service.config.properties.FuiouProperties;
import com.hjb.service.domain.siteuser.SiteUser;
import com.hjb.service.domain.siteuser.SiteUserAccountLog;
import com.hjb.service.domain.siteuser.SiteUserAccountLogExample;
import com.hjb.service.domain.siteuser.SiteUserExample;
import com.hjb.service.domain.siteuseraccount.SiteUserAccount;
import com.hjb.service.domain.siteuseraccount.SiteUserAccountExample;
import com.hjb.service.domain.siteuseraccount.SiteUserBankcard;
import com.hjb.service.domain.withdraw.PayCashWithdraw;
import com.hjb.service.domain.withdraw.PayCashWithdrawExample;
import com.hjb.service.gateway.fuiou.FuiouFHTService;
import com.hjb.service.gateway.fuiou.FyPayConstant;
import com.hjb.service.gateway.fuiou.FyPayWithDrawQuery;
import com.hjb.service.mapper.PayCashWithdrawMapper;
import com.hjb.service.mapper.SiteUserAccountLogMapper;
import com.hjb.service.mapper.SiteUserAccountMapper;
import com.hjb.service.mapper.SiteUserBankcardMapper;
import com.hjb.service.mapper.SiteUserMapper;
import com.hjb.service.user.SiteSysAccountService;
import com.hjb.service.utils.DateUtil;
import com.hjb.service.utils.MapUtil;
import com.hjb.service.withdraw.FYWithDrawService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by gy on 2017/7/28.
 * 提现接口实现
 */
@Service
public class FYWithDrawServiceImpl implements FYWithDrawService {

	private Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
	private SiteUserMapper siteUserMapper;
	@Autowired
	private PayCashWithdrawMapper payCashWithdrawMapper;
	@Autowired
	private SiteUserBankcardMapper siteUserBankcardMapper;
	@Autowired
	private SiteUserAccountMapper siteUserAccountMapper;
	@Autowired
	private FuiouProperties fuiouProperties;
	@Autowired
	private SiteSysAccountService siteSysAccountService;
	@Autowired
	private SiteUserAccountLogMapper siteUserAccountLogMapper;

	@Override
	public Map<String, Object> withdraw(PayCashWithdraw payCashWithdraw) {
		Map<String, Object> resMap = new HashMap<String, Object>();
		Map<String, Object> dataMap = new HashMap<String, Object>();
		try {
			if (payCashWithdraw.getAmount() == null){
				resMap.put("result_code",MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "提现金额为空");
				return resMap;
			}
			if (new BigDecimal(0).compareTo(payCashWithdraw.getAmount()) !=-1){//充值金额大于0
				resMap.put("result_code",MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "提现金额有误");
				return resMap;
			}
			//查询用户信息
			SiteUser siteUser = new SiteUser();
			SiteUserExample siteUserExample = new SiteUserExample();
			siteUserExample.createCriteria().andUserIdEqualTo(payCashWithdraw.getUserId());
			List<SiteUser> siteUserList = siteUserMapper.selectByExample(siteUserExample);
			if (siteUserList == null || siteUserList.size() == 0){
				resMap.put("result_code", MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "无用户信息");
				return resMap;
			}
			//查询用户绑卡信息
			SiteUserBankcard siteUserBankcard = new SiteUserBankcard();
			SiteUserBankcard record = new SiteUserBankcard();
			record.setUserId(payCashWithdraw.getUserId());
			record.setStatus(1);
			record.setUnbindStatus(0);
			record.setCardType(2);
			List<SiteUserBankcard> userBankcards = siteUserBankcardMapper.selectByExample(record);
			if (userBankcards == null || userBankcards.size() == 0){
				resMap.put("result_code", MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "无用户绑卡信息");
				return resMap;
			}
			//查询用户账户信息
			SiteUserAccountExample userAccountExample = new SiteUserAccountExample();
			userAccountExample.createCriteria().andUserIdEqualTo(payCashWithdraw.getUserId());
			List<SiteUserAccount> userAccountList =  siteUserAccountMapper.selectByExample(userAccountExample);
			if (userAccountList == null || userAccountList.size() == 0){//无用户账户记录
				log.info("未查到用户账户记录，userId："+payCashWithdraw.getUserId());
				resMap.put("result_code", MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "无用户账户信息");
				return resMap;
			}
			SiteUserAccount siteUserAccount = userAccountList.get(0);

			if (siteUserAccount.getFrozenAccount().compareTo(payCashWithdraw.getAmount()) ==-1){
				resMap.put("result_code",MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "账户冻结金额小于提现金额");
				return resMap;
			}
			siteUser = siteUserList.get(0);
			siteUserBankcard = userBankcards.get(0);
			//调取三方提现
			Payforreq payforreq  = new Payforreq();
			payforreq.setMchntCd(fuiouProperties.getProxyMerchId());
			payforreq.setVer(FyPayConstant.fy_pay_version);
			payforreq.setMerdt(DateUtil.format(new Date(), DateUtil.FORMAT_LONG_YMD));
			payforreq.setOrderno(payCashWithdraw.getOrderId());
			payforreq.setBankno(siteUserBankcard.getBankCode());
			payforreq.setCityno(siteUserBankcard.getCityCode());
			payforreq.setAccntno(siteUserBankcard.getCardNo());
			payforreq.setAccntnm(siteUser.getName());
			String amt = payCashWithdraw.getAmount().multiply(new BigDecimal(100))+"";
			if(amt.indexOf(".")>0){
				amt = amt.substring(0, amt.lastIndexOf("."));
			}
			payforreq.setAmt(amt);
			//将平台生成的流水号传到富友企业流水号，在对账文件中代付交易会返回企业流水号（即为平台流水号），对账使用
			payforreq.setEntseq(payCashWithdraw.getOrderId());
			payforreq.setMobile(siteUser.getBankPhone());
			Map<String, String> map = new HashMap<String, String>();
			map.put("url", fuiouProperties.getProxyUrl());
			map.put("md5Key", fuiouProperties.getProxyKey());
			map.put("timeout", "60000");
			map.put("reqtype", FyPayConstant.withdraw_code);
			String response = FuiouFHTService.payforreq(payforreq, map);
			//业务处理
			if (StringUtils.isBlank(response)){
				log.info("提现富有返回数据为空");
				resMap.put("result_code", MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "提现失败");
				return resMap;
			}
			resMap.put("result_code", MapUtil.INTF_ERR_CODE);
			String code = response.substring(response.indexOf("<ret>")+5,response.indexOf("</ret>"));
			String mes = response.substring(response.indexOf("<memo>")+6,response.indexOf("</memo>"));
			if ("000000".equals(code)){
				//更新提现记录信息 设置状态为充值中
				PayCashWithdraw payCashWithdraw1 = getWithdraw(payCashWithdraw,siteUserBankcard.getCardNo());

				if (payCashWithdraw1 == null){
					log.info("没有状态是0的提现记录，订单号："+payCashWithdraw.getOrderId());
					resMap.put("result_code", MapUtil.INTF_ERR_CODE);
					resMap.put("result_info", "没有提现记录");
					return resMap;
				}
				payCashWithdraw1.setRetCode(code);
				payCashWithdraw1.setMsg(mes);
				payCashWithdraw1.setCallbackMsg(response);
				payCashWithdrawMapper.updateByPrimaryKey(payCashWithdraw1);
				resMap.put("result_code", MapUtil.INTF_SUC_CODE);
			}
			resMap.put("result_info", mes);

		}catch (Exception e){
			log.info("提现失败"+e);
			resMap.put("result_code",MapUtil.INTF_ERR_CODE);
			resMap.put("result_info", "请求失败");
		}
		return resMap;
	}

	@Override
	public void withdrawQuery(PayCashWithdraw payCashWithdraw) throws RuntimeException{
		if (payCashWithdraw != null){
			String startdt =DateUtil.format(payCashWithdraw.getSendTime(), DateUtil.FORMAT_LONG_YMD);
			String enddt	=DateUtil.format(new Date(), DateUtil.FORMAT_LONG_YMD);
			Qrytransreq qrytransreq  = new Qrytransreq();
			qrytransreq.setMchntCd(fuiouProperties.getProxyMerchId());

			qrytransreq.setOrderno(payCashWithdraw.getOrderId());
			qrytransreq.setVer(FyPayConstant.fy_pay_version);
			qrytransreq.setBusicd(FyPayConstant.payment);

			qrytransreq.setStartdt(startdt);
			qrytransreq.setEnddt(enddt);
			Map<String, String> map = new HashMap<String, String>();
			map.put("url", fuiouProperties.getProxyUrl());
			map.put("md5Key", fuiouProperties.getProxyKey());
			map.put("timeout", "60000");
			map.put("reqtype", FyPayConstant.query_code);

			String response = FuiouFHTService.queryTrans(qrytransreq, map);
			log.info("富友提现交易查询返回："+response);
			Map<String,Object> returnMap = FuiouFHTService.parseReturnXml(response);
			if(returnMap == null || !FyPayConstant.success.equals(returnMap.get("ret"))){
				log.info((String) returnMap.get("memo"));
				return;
			}
			List<FyPayWithDrawQuery> transList = (List<FyPayWithDrawQuery>)returnMap.get("transList");
			if(transList!=null && transList.size()>0) {
				FyPayWithDrawQuery fyPayWithDrawQuery = transList.get(0);
				log.info("富友提现交易查询返回,封装对象数据：fyPayWithDrawQuery=" + fyPayWithDrawQuery.toString());
				dealWithDraw(fyPayWithDrawQuery);
			}
		}
	}

	private PayCashWithdraw getWithdraw(PayCashWithdraw payCashWithdraw,String cardNo){
		PayCashWithdrawExample payCashWithdrawExample = new PayCashWithdrawExample();
		payCashWithdrawExample.createCriteria().andStatusEqualTo(0).andUserIdEqualTo(payCashWithdraw.getUserId())
				.andAmountEqualTo(payCashWithdraw.getAmount()).andOrderIdEqualTo(payCashWithdraw.getOrderId());
		List<PayCashWithdraw> payCashWithdrawList= payCashWithdrawMapper.selectByExample(payCashWithdrawExample);
		if (payCashWithdrawList == null || payCashWithdrawList.size()< 1){
			return null;
		}
		PayCashWithdraw payCashWithdraw1 = payCashWithdrawList.get(0);
		payCashWithdraw1.setSendTime(new Date());
		payCashWithdraw1.setStatus(2);
		payCashWithdraw1.setCardNo(cardNo);
		payCashWithdraw1.setPayType(1);
		return payCashWithdraw1;
	}
	//处理体现业务
	@Transactional
	public String dealWithDraw(FyPayWithDrawQuery fyPayWithDrawQuery){
		//try {
			String orderNo = fyPayWithDrawQuery.getOrderno();//订单号
			String message = fyPayWithDrawQuery.toString();//三方返回信息
			String code = fyPayWithDrawQuery.getCode();//三方返回码
			String errorInfo = fyPayWithDrawQuery.getMessage();//错误信息信息
			String status = fyPayWithDrawQuery.getState();//三方返回状态
			String dealTime = null;//三方处理时间
			BigDecimal amount =new BigDecimal(fyPayWithDrawQuery.getAmt()).divide(new BigDecimal(100));//交易金额
			BigDecimal fee = new BigDecimal("2");//交易手续费

			if ("0".equals(status) || "3".equals(status) || "7".equals(status)){
				log.info("三方返回状态为处理中，不需处理业务，状态："+status);
				return null;
			}
			//1.获取提现记录
			PayCashWithdrawExample example = new PayCashWithdrawExample();
			example.createCriteria().andOrderIdEqualTo(orderNo).andAmountEqualTo(amount).andStatusEqualTo(2);
			List<PayCashWithdraw> payCashWithdrawList = payCashWithdrawMapper.selectByExample(example);
			if (payCashWithdrawList == null || payCashWithdrawList.size() ==0){
				log.info("未查到等待回调的提现记录，订单号："+orderNo +"提现金额："+amount);
				return null;
			}
			//2.判断是否处理提现记录 提现金额=用户账户表中体现冻结金额
			PayCashWithdraw payCashWithdraw = payCashWithdrawList.get(0);
			//查询用户账户信息
			SiteUserAccountExample userAccountExample = new SiteUserAccountExample();
			userAccountExample.createCriteria().andUserIdEqualTo(payCashWithdraw.getUserId());
			List<SiteUserAccount> userAccountList =  siteUserAccountMapper.selectByExample(userAccountExample);
			if (userAccountList == null || userAccountList.size() == 0){//无用户账户记录
				log.info("未查到用户账户记录，userId："+payCashWithdraw.getUserId());
				return null;
			}

			SiteUserAccount siteUserAccount = userAccountList.get(0);
			BigDecimal frozenAmount = siteUserAccount.getFrozenAccount();//提现冻结金额
			if (amount.compareTo(frozenAmount) == -1){//提现金额大于冻结金额
				//3.更新充值记录状态
				switch (status){//成功
					case "1":
						payCashWithdraw.setStatus(1);
						break;
					case "2"://失败
						payCashWithdraw.setStatus(3);
						break;
				}
				payCashWithdraw.setReplyTime(new Date());
				payCashWithdraw.setCallbackMsg(message);
				payCashWithdraw.setPayFee(fee);
				payCashWithdraw.setMsg(errorInfo);
				payCashWithdraw.setRetCode(code);

				payCashWithdrawMapper.updateByExampleSelective(payCashWithdraw,example);
				//日志
				SiteUserAccountLogExample siteUserAccountLogExample = new SiteUserAccountLogExample();
				siteUserAccountLogExample.createCriteria().andOrderIdEqualTo(payCashWithdraw.getOrderId()).andStatusEqualTo(3);
				List<SiteUserAccountLog> siteUserAccountLogs = siteUserAccountLogMapper.selectByExample(siteUserAccountLogExample);
				if (siteUserAccountLogs == null || siteUserAccountLogs.size() < 1){
					log.info("未查到状态是3的用户账户日志记录，orderId："+payCashWithdraw.getOrderId());
					return null;
				}
				SiteUserAccountLog siteUserAccountLog = siteUserAccountLogs.get(0);

				// 4.判断是否提现成功 成功更新用户账户表
				if (1 == payCashWithdraw.getStatus()){
					siteUserAccount.setFrozenAccount(frozenAmount.divide(amount));
					SiteUserAccountExample accountExample = new SiteUserAccountExample();
					accountExample.createCriteria().andUserIdEqualTo(payCashWithdraw.getUserId()).andFrozenAccountEqualTo(amount);
					siteUserAccountMapper.updateAccountExample(siteUserAccount,accountExample);
					String accType = "";
					if (2== siteUserAccountLog.getAcctType()){
						accType = "定期赎回";
						//系统账户
						siteSysAccountService.updateBanlanceByUserId(Constants.SYS_ACCOUNT_10000, amount, BigDecimal.ZERO, Constants.ACCOUNT_LOG_TYPE_2,
								payCashWithdraw.getUserId(), Constants.SYS_ACCOUNT_10000,
								orderNo, "", "", payCashWithdraw.getOrderId()+payCashWithdraw.getCardNo(), accType, payCashWithdraw.getUserId()+"");
						//手续费账户
						siteSysAccountService.updateBanlanceByUserId(Constants.SYS_ACCOUNT_10004, fee, BigDecimal.ZERO, Constants.ACCOUNT_LOG_TYPE_2,
								payCashWithdraw.getUserId(), Constants.SYS_ACCOUNT_10004,
								orderNo, "", "", payCashWithdraw.getOrderId()+payCashWithdraw.getCardNo(), accType, payCashWithdraw.getUserId()+"");
						//定期账户
						siteSysAccountService.updateBanlanceByUserId(Constants.SYS_ACCOUNT_10003, fee.add(amount), BigDecimal.ZERO, Constants.ACCOUNT_LOG_TYPE_2,
								payCashWithdraw.getUserId(), Constants.SYS_ACCOUNT_10003,
								orderNo, "", "", payCashWithdraw.getOrderId()+payCashWithdraw.getCardNo(), accType, payCashWithdraw.getUserId()+"");
					}
					if (3== siteUserAccountLog.getAcctType()){
						accType = "活期赎回";
						//系统账户
						siteSysAccountService.updateBanlanceByUserId(Constants.SYS_ACCOUNT_10000, amount, BigDecimal.ZERO, Constants.ACCOUNT_LOG_TYPE_3,
								payCashWithdraw.getUserId(), Constants.SYS_ACCOUNT_10000,
								orderNo, "", "", payCashWithdraw.getOrderId()+payCashWithdraw.getCardNo(), accType, payCashWithdraw.getUserId()+"");
						//手续费账户
						siteSysAccountService.updateBanlanceByUserId(Constants.SYS_ACCOUNT_10004, fee, BigDecimal.ZERO, Constants.ACCOUNT_LOG_TYPE_3,
								payCashWithdraw.getUserId(), Constants.SYS_ACCOUNT_10004,
								orderNo, "", "", payCashWithdraw.getOrderId()+payCashWithdraw.getCardNo(), accType, payCashWithdraw.getUserId()+"");
						//活期账户
						siteSysAccountService.updateBanlanceByUserId(Constants.SYS_ACCOUNT_10002, fee.add(amount), BigDecimal.ZERO, Constants.ACCOUNT_LOG_TYPE_3,
								payCashWithdraw.getUserId(), Constants.SYS_ACCOUNT_10002,
								orderNo, "", "", payCashWithdraw.getOrderId()+payCashWithdraw.getCardNo(), accType, payCashWithdraw.getUserId()+"");
					}
					siteUserAccountLog.setStatus(1);
				}
				if (3 == payCashWithdraw.getStatus()) {
					siteUserAccountLog.setStatus(2);
				}
				//更新日志
				siteUserAccountLogMapper.updateByPrimaryKey(siteUserAccountLog);
			}else {
				log.info("金额不匹配---冻结提现金额："+frozenAmount +"提现金额："+amount);
				return null;
			}
		/*}catch (Exception e){
			log.info("处理提现业务逻辑失败");
			return null;
		}*/
		return "OK";
	}

}
